//
//  GoogleDriveMediaShareCommunity.m
//  MediaShareBB
//
//  Created by Artak Gevorgyan on 5/23/13.
//  Copyright (c) 2013 InnoriseEntertainment. All rights reserved.
//

#import "GoogleDriveMediaShareCommunity.h"
#import "MediaShareBBUtilityMethods.h"
#import "AppDelegate.h"

#import "GTLDrive.h"
#import "MediaShareData.h"


NSString* const kKeychainItemNameDrive = @"Matit: Google Drive";

@interface GoogleDriveMediaShareCommunity() {
	NSString* _clientId;
	NSString* _secretId;
	NSString* _filePath;
	NSString* _mimeType;
	MediaShareData* _sharedMediaData;
    GTLServiceTicket* _uploadFileTicket;
	GTMOAuth2ViewControllerTouch* _signInController;
	BOOL _isAuthorized;
    NSString* _sharedMedialink;
}

@end

@implementation GoogleDriveMediaShareCommunity

-(id) init {
	self = [super init];
	if (self) {
		super.name = @"GoogleDrive";
		super.communityType = MEDIA_SHARE_COMMUNITY_GOOGLE_DRIVE;
		super.supportedMediaTypes = [[NSArray alloc] initWithObjects:
									 [NSNumber numberWithInt:IMAGE_MEDIA_TYPE],
									 [NSNumber numberWithInt:VIDEO_MEDIA_TYPE],
									 [NSNumber numberWithInt:URL_MEDIA_TYPE], nil];
	}
	return self;
}

-(NSString*) description {
	NSString* d = @"GoogleDrive description";
	return d;
}

-(void) configureWithCredentials:(NSDictionary*) credentials {
	_clientId = [credentials valueForKey:@"clientId"];
	_secretId = [credentials valueForKey:@"clientSecret"];
	GTMOAuth2Authentication *auth =
	[GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemNameDrive
														  clientID:_clientId
													  clientSecret:_secretId];
	if ([auth canAuthorize]) {
		[self isAuthorizedWithAuthentication:auth];
	}
}

-(void) login {
    if (!_isAuthorized) {
		// Sign in.
        SEL finishedSelector = @selector(viewController:finishedWithAuth:error:);
        GTMOAuth2ViewControllerTouch* authViewController =
        [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDriveFile
                                                   clientID:_clientId
                                               clientSecret:_secretId
                                           keychainItemName:kKeychainItemNameDrive
                                                   delegate:self
                                           finishedSelector:finishedSelector];
		_signInController = authViewController;
		_signInController.delegate = self;
        [self presentViewController:authViewController];
    } else {
		if ([MediaShareBBUtilityMethods isObject:super.delegate
							  respondsToSelector:@selector(loginSuccess)]) {
			[super.delegate loginSuccess];
		}
    }
}

//Superclass method
-(void) loginWithAnotherUser {
    [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemNameDrive];
    [[self driveService] setAuthorizer:nil];
    _isAuthorized = NO;
    SEL finishedSelector = @selector(viewController:finishedWithAuth:error:);
    GTMOAuth2ViewControllerTouch* authViewController =
    [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDriveFile
                                               clientID:_clientId
                                           clientSecret:_secretId
                                       keychainItemName:kKeychainItemNameDrive
                                               delegate:self
                                       finishedSelector:finishedSelector];
    _signInController = authViewController;
    _signInController.delegate = self;
    [self presentViewController:authViewController];
}

//Superclass method
-(NSString*) getUserName {
    GTMOAuth2Authentication* auth = self.driveService.authorizer;
    BOOL isSignedIn = auth.canAuthorize;
    if (isSignedIn) {
        return auth.userEmail;
    } else {
        return nil;
    }
}

//Superclass method
-(NSString*) sharedMediaLink {
    return _sharedMedialink;
}

-(void) shareMedia:(MediaShareData*) data {
	if ([super isValidMediaType:data.mediaType]) {
		_sharedMediaData = data;
		if ([MediaShareBBUtilityMethods isObject:super.delegate
							  respondsToSelector:@selector(willSharingMedia:through:)]) {
			[super.delegate willSharingMedia:_sharedMediaData through:self];
			if (IMAGE_MEDIA_TYPE == data.mediaType) {
				NSString* s = [NSString stringWithFormat:@"%@.png", _sharedMediaData.fileName];
				_filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:s];
				[_sharedMediaData.data writeToFile:_filePath atomically:YES];
				_mimeType = @"image/png";
			}
            if (VIDEO_MEDIA_TYPE == data.mediaType) {
				_filePath = _sharedMediaData.path;
				_mimeType = @"video/mp4";
            }
			[self uploadData];
		}
	} else {
		NSLog(@"%s: Unsupported media type:%d", __PRETTY_FUNCTION__, data.mediaType);
		if ([MediaShareBBUtilityMethods isObject:super.delegate
							  respondsToSelector:@selector(didFailedSharingMedia:through:withError:)]) {
			[super.delegate didFailedSharingMedia:_sharedMediaData through:self withError:nil];
		}
	}
}

#pragma mark - GTMOAuth2ViewControllerTouchDelegate methods

-(void) signInProcessCanceled {
	AppDelegate* app = [UIApplication sharedApplication].delegate;
	UIViewController* controller = app.window.rootViewController;
//	UIViewController* controller = [super.delegate targetViewController];
	[controller dismissViewControllerAnimated:YES completion:nil];
	[_signInController cancelSigningIn];
	if ([MediaShareBBUtilityMethods isObject:super.delegate
						  respondsToSelector:@selector(loginCanceled)]) {
		[super.delegate loginCanceled];
	}
}

#pragma mark - Private methods

-(void) changeFilePermissions:(GTLDriveFile*) uploadedFile {
    GTLServiceDrive* service = [self driveService];
    GTLDrivePermission* permission = [GTLDrivePermission object];
    permission.type= @"anyone";
    permission.role = @"reader";
    permission.value = @"none";
    GTLQueryDrive *queryForPermissions =
    [GTLQueryDrive queryForPermissionsInsertWithObject:permission
                                                fileId:uploadedFile.identifier];
    
    [service executeQuery:queryForPermissions
        completionHandler:^(GTLServiceTicket *ticket,
                            GTLDrivePermission *permission, NSError *error) {
            if (error == nil) {
                NSLog(@"sharing permissions changed !");
            } else {
                NSLog(@"An error occurred: %@", error);
            }
        }];
}

-(void) uploadData {
    NSFileHandle* fileHandle = [NSFileHandle fileHandleForReadingAtPath:_filePath];
    if (fileHandle) {
        GTLServiceDrive* service = [self driveService];
        GTLUploadParameters* uploadParameters = [GTLUploadParameters uploadParametersWithData:_sharedMediaData.data
																					 MIMEType:_mimeType];
        GTLDriveFile* newFile = [GTLDriveFile object];
        newFile.title = _sharedMediaData.fileName;
        GTLQueryDrive* query = [GTLQueryDrive queryForFilesInsertWithObject:newFile
                                                           uploadParameters:uploadParameters];
        _uploadFileTicket = [service executeQuery:query
                                completionHandler:^(GTLServiceTicket* ticket,
                                                    GTLDriveFile* uploadedFile,
                                                    NSError* error) {
                                    // Callback
                                    _uploadFileTicket = nil;
                                    if (error == nil) {
										NSLog(@"success !");
                                        [self changeFilePermissions:uploadedFile];                                                                     
                                        _sharedMedialink = [NSString stringWithFormat:@"%@", uploadedFile.alternateLink];
										if ([MediaShareBBUtilityMethods isObject:super.delegate
															  respondsToSelector:@selector(didFinishSharingMedia:through:)]) {
											[super.delegate didFinishSharingMedia:_sharedMediaData
																		  through:self];
										}
                                    } else {
										NSLog(@"Failed !");
										if ([MediaShareBBUtilityMethods isObject:super.delegate
															  respondsToSelector:@selector(didFailedSharingMedia:through:withError:)]) {
											[super.delegate didFailedSharingMedia:_sharedMediaData
																		  through:self
																		withError:nil];
										}
                                    }
                                }];
    }
}

-(void) viewController:(GTMOAuth2ViewControllerTouch*) viewController
	  finishedWithAuth:(GTMOAuth2Authentication*) auth
				 error:(NSError*) error {
	AppDelegate* app = [UIApplication sharedApplication].delegate;
	UIViewController* controller = app.window.rootViewController;
//	UIViewController* controller = [super.delegate targetViewController];
	[controller dismissViewControllerAnimated:YES completion:nil];

	if (error) {
		if ([error code] != kGTMOAuth2ErrorWindowClosed) {
			NSLog(@"%s: Unresolved sign in error: %@ %@", __PRETTY_FUNCTION__,
				  error, [error userInfo]);
		}
		if ([MediaShareBBUtilityMethods isObject:super.delegate
							  respondsToSelector:@selector(loginFailedWithError:)]) {
			[super.delegate loginFailedWithError:error];
		}
	} else {
		NSLog(@"%s: Success login", __PRETTY_FUNCTION__);
		[self isAuthorizedWithAuthentication:auth];
		if ([MediaShareBBUtilityMethods isObject:super.delegate
							  respondsToSelector:@selector(loginSuccess)]) {
			[super.delegate loginSuccess];
		}
	}
}

-(GTLServiceDrive*) driveService {
    static GTLServiceDrive* service = nil;
    if (!service) {
        service = [[GTLServiceDrive alloc] init];

        // Have the service object set tickets to fetch consecutive pages
        // of the feed so we do not need to manually fetch them.
        service.shouldFetchNextPages = YES;

        // Have the service object set tickets to retry temporary error conditions
        // automatically.
        service.retryEnabled = YES;
    }
    return service;
}

-(void) presentViewController:(GTMOAuth2ViewControllerTouch*) vc {
	if ([MediaShareBBUtilityMethods isObject:super.delegate
						  respondsToSelector:@selector(targetViewController)] ) {
//		UIViewController* controller = [super.delegate targetViewController];
		AppDelegate* app = [UIApplication sharedApplication].delegate;
		UIViewController* controller = app.window.rootViewController;
		if (IPAD) {
			vc.modalPresentationStyle = UIModalPresentationFormSheet;
		}
		[controller presentViewController:vc animated:YES completion:nil];
	}
}

-(void) isAuthorizedWithAuthentication:(GTMOAuth2Authentication*) auth {
    [[self driveService] setAuthorizer:auth];
	_isAuthorized = YES;
}

@end
